package spring.chatroom.java_chatroom.server;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import spring.chatroom.java_chatroom.mapper.ChatInfoMapper;
import spring.chatroom.java_chatroom.mapper.FriendTableMapper;
import spring.chatroom.java_chatroom.mapper.SessionIdMapper;
import spring.chatroom.java_chatroom.mapper.UserMapper;
import spring.chatroom.java_chatroom.mapper.plusSql.UserSql;
import spring.chatroom.java_chatroom.common.utils.TypeTran;
import spring.chatroom.java_chatroom.pojo.model.*;
import spring.chatroom.java_chatroom.pojo.response.*;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

@Slf4j
@Service
public class UserServer {

    @Autowired
    UserMapper userMapper;

    @Autowired
    MesSendServer mesSendServer;

    @Autowired
    FriendTableMapper friendTableMapper;

    @Autowired
    ChatInfoMapper chatInfoMapper;

    @Autowired
    SessionIdMapper sessionidMapper;

    @Autowired
    private UserSql userSql;

    //若没有就返回一个空的对象
    public userInfo getUserInfoByNameAndPassWord(userInfo user) {
        userInfo u = userMapper.selectUsersByNameAndPassWord(user);
        return u == null ? new userInfo() : u;
    }

    //注册
    public userInfo register(userInfo user) {
        try {
            user = userMapper.insertUsers(user) == 1 ? user : new userInfo();

            return user;
        } catch (DuplicateKeyException e) {//如果插入的
            System.out.println("用户名重复: " + user.getUserName());
            return new userInfo();
        }
    }

    //根据userId来获得user的信息
    public userInfoResp getUserInfo(Integer userId) {
        QueryWrapper<userInfo> qw = new QueryWrapper<>();
        qw.eq("user_id", userId)
                .eq("delete_flag", 0);
        userInfo u = userMapper.selectOne(qw);

        userInfoResp ret = new userInfoResp();

        BeanUtils.copyProperties(u, ret);

        return ret;
    }

    //特别的格式复制方法
    List<friendListResp> tran(List<friendTable> friendId) {
        List<friendListResp> ret = new ArrayList<>();
        for (friendTable f : friendId) {
            friendListResp friend = new friendListResp();
            friend.setId(f.getSessionId());
            friend.setFriendId(f.getUserId());
            ret.add(friend);
        }
        return ret;
    }

    //还需要查询到最近的消息
    public List<friendListResp> getFriendSessionList(Integer userId) {

        List<friendTable> friendId = friendTableMapper.getFriendId(userId);

        if(friendId.isEmpty()) {
            return Collections.emptyList();
        }

        //将friendId 和sessionId储存
        List<friendListResp> retList = tran(friendId);

        //更具ids获取到userInfo
        List<userInfo> userInfo = userSql.getUsersByIds(
                friendId.stream().map(friendTable::getUserId).collect(Collectors.toList()));

        //将userInfo表中的元素装换到friendListResp userName
        retList = TypeTran.ListTran(userInfo, retList);

        //根据sessionId 来获取到最近的一条数据
        for (friendListResp f : retList) {
            //查询到消息
            QueryWrapper<chatInfo> qw = new QueryWrapper<>();

            qw.eq("session_id", f.getId())
                    .orderByDesc("create_time")
                    .eq("delete_flag", 0)
                    .last("limit 1");

            chatInfo list = chatInfoMapper.selectOne(qw);

            if (list != null) {
                f.setContent(list.getContent());
            } else {
                f.setContent("");
            }
        }

        return retList;
    }

    //可以使用笛卡尔积来查找多表数据 联合chatInfo userInfo这俩表
    public List<historyInfoResp> sessionList(Integer sessionId) {
        List<historyInfoResp> historyInfoResp = chatInfoMapper.selectChatInfoList(sessionId);
        Collections.reverse(historyInfoResp);
        return historyInfoResp;
    }

    //根据sessionId来获取朋友到历史记录，是最近的 单表查询
    public List<historyInfoResp> sessionList1(Integer sessionId) {
        //升序
        QueryWrapper<chatInfo> qw = new QueryWrapper<>();
        System.out.println(qw.eq("session_id", sessionId)
                .orderByDesc("create_time")
                .last("limit 100").
                eq("delete_flag", 0));

        //按升序来排序俩天记录
        List<chatInfo> list = chatInfoMapper.selectList(qw);

        //给逆序为升序
        Collections.reverse(list);

        QueryWrapper<userInfo> qw1 = new QueryWrapper<>();

        List<userInfoResp> userInfos = new ArrayList<>();

        //获得username
        for (int i : list.stream().map(chatInfo::getUserId).collect(Collectors.toList())) {
            userInfoResp u = getUserInfo(i);
            userInfos.add(u);
        }

        //将username userId复制到resp中
        List<historyInfoResp> retList = TypeTran.ListTran(userInfos, historyInfoResp.class);
        //复制content sessionId
        return TypeTran.ListTran(list, retList);
    }

    public userInfo getUserInfoByName(String username) {
        QueryWrapper<userInfo> qw = new QueryWrapper<>();
        qw.eq("user_name", username).eq("delete_flag", 0);
        return userMapper.selectOne(qw);
    }

    public sessionId addFriends(Integer userId, Integer friendId) {
        //判断一下之前是不是好友
        Integer friendAndDeleteId = friendTableMapper.isFriendAndDelete(userId, friendId);
        if (friendAndDeleteId != null) {

            //那么只需要跟新为0就好
            UpdateWrapper<friendTable> uw = new UpdateWrapper<>();
            uw.in("user_id", List.of(userId, friendId))
                    .set("delete_flag", 0);
            friendTableMapper.update(uw);

            log.info("添加好友 是之前已经添加啊过的 userId={} friendId={} sessionId = {}", userId, friendId, friendAndDeleteId);

            return new sessionId(friendAndDeleteId);
        }


        //先检查这俩个是不是已经是朋友了 还有这俩个是不是存在的
        if (!friendTableMapper.isFriend(userId, friendId).isEmpty() || userMapper.getUserByUserId(friendId) == null) {
            log.info("已经添加或者朋友不存在: userId={} friendId={}", userId, friendId);
            return null;
        }

        //为这俩好友创建sessionId
        sessionId s = new sessionId();

        sessionidMapper.insertSessionId(s);

        insertList(s.getId(), List.of(userId, friendId));

        return s;
    }

    private void insertList(int sessionId, List<Integer> ids) {
        friendTable s = new friendTable();
        for (Integer id : ids) {
            s.setSessionId(sessionId);
            s.setUserId(id);
            friendTableMapper.insert(s);
        }
    }

    @Transactional
    public String delMsg(Integer msgId) {
        UpdateWrapper<chatInfo> uw = new UpdateWrapper<>();
        uw.set("delete_flag", 1)
                .eq("id", msgId);

        if (chatInfoMapper.update(uw) == 1) {
            log.info("删除成功msg={}", msgId);
            return "";
        } else {
            //回滚事务
            log.error("事务回滚 msgId = " + msgId);
            throw new RuntimeException("参数错误 事务回滚了 session_id");
        }
    }

    //将请求通过websocket发送给friendId
    public boolean tranFriendReq(Integer sendId, Integer receiveId,String content) throws IOException {

        userInfo user = userMapper.getUserByUserId(sendId);
        user.setPassword("");

        addFriendInfo a = new addFriendInfo();
        a.setType("addFriend");
        a.setSendUser(user);
        a.setContent(content);

        mesSendServer.tranFriendReq(receiveId, a);
        return true;
    }

    public List<friendSessionResp> getFriendList(Integer userId) {
        // 得到friendId
        List<friendTable> ids = friendTableMapper.getFriendId(userId);

        if(ids == null || ids.isEmpty()) {
            return Collections.emptyList();
        }

        QueryWrapper<userInfo> qw = new QueryWrapper<>();

        qw.in("user_id", ids.stream().map(friendTable::getUserId).collect(Collectors.toList()))
                .eq("delete_flag", 0)
                .last(" order by user_id asc");
        List<userInfo> userInfos = userMapper.selectList(qw);

        List<friendSessionResp> friendSessionResps = tranToFriendSessionResp(userInfos, ids);

        log.info("friendSessionResps = {}", friendSessionResps);

        return friendSessionResps;

    }

    private List<friendSessionResp> tranToFriendSessionResp(List<userInfo> userInfos, List<friendTable> ids) {
        List<friendSessionResp> retList = new ArrayList<>();
        for (int i = 0; i < ids.size(); i++) {
            friendSessionResp f = new friendSessionResp();
            f.setId(ids.get(i).getSessionId());
            f.setFriendId(ids.get(i).getUserId());
            f.setUserName(userInfos.get(i).getUserName());
            retList.add(f);
        }

        return retList;
    }



    public void delFriend(Integer sessionId) {
        UpdateWrapper<friendTable> uw = new UpdateWrapper<>();
        uw.set("delete_flag", 1).eq("session_id", sessionId);

        int i = friendTableMapper.update(uw);

        if (i != 2) {
            log.info("好友删除失败 sessionId={}", sessionId);
        }
        log.info("好友删除成功 sessionId={}", sessionId);
    }
}
